package com.thx.common.util;

import com.thx.common.web.WebConstant;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

/**
 * 这里的加密指的是宏观的加密，也可能选择的加密类型是明文，即不进行hash加密处理， source指的是要匹配的数据（没有进行加密），encrypted指的是被匹配 的数据（进行过加密）.
 *
 * @author : calonlan
 */
public class PasswordUtil {

  private enum EncryptType {
    //加密类型，目前支持以下四种，速度从高到低、安全性从低到高依次是：PLAINTEXT、MD5、SHA1、BCYRPT
    //可逆的加密方式：DES
    MD5("md5"), SHA1("sha-1"), PLAINTEXT("plaintext"), BCYRPT("bcyrpt"), DES("des");

    private String value;

    EncryptType(String value) {
      this.value = value;
    }
  }

  /**
   * 验证是否匹配.
   *
   * @param source 没有进行加密的数据
   * @param encrypted 进行过加密的数据
   * @param salt 盐
   */
  public static Boolean isMatch(String source, String encrypted, String salt) {
    //加密方式
    String algorithmName = AppContext.getProperties(WebConstant.ENCRYPTED_TYPE);

    //明文密码
    if (EncryptType.PLAINTEXT.value.equals(algorithmName)) {
      return source.equals(encrypted);
      //MD5加密
    } else if (EncryptType.MD5.value.equals(algorithmName)) {
      //加密次数
      int hashIterations = Integer.parseInt(AppContext.getProperties(
          WebConstant.ENCRYPTED_NUM));
      try {
        return EncryptUtil.checkByMD5(source, salt, hashIterations, encrypted);
      } catch (UnsupportedEncodingException ex) {
        ex.printStackTrace();
      } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
      }
      // SHA1加密
    } else if (EncryptType.SHA1.value.equals(algorithmName)) {
      //加密次数
      int hashIterations = Integer.parseInt(AppContext.getProperties(
          WebConstant.ENCRYPTED_NUM));
      try {
        return EncryptUtil.checkBySha1(source, salt, hashIterations, encrypted);
      } catch (UnsupportedEncodingException ex) {
        ex.printStackTrace();
      } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
      }
      // BCYRPT加密
    } else if (EncryptType.BCYRPT.value.equals(algorithmName)) {
      return EncryptUtil.checkBybcrypt(source, encrypted);
      //DES 加密
    } else if (EncryptType.DES.value.equals(algorithmName)) {
      try {
        return EncryptUtil.checkByDes(source, encrypted);
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    } else {
      return source.equals(encrypted);
    }
    return source.equals(encrypted);
  }


  /**
   * 加密.
   *
   * @param plaintext 源数据
   * @param salt 盐
   */
  public static String encrypt(String plaintext, String salt) {
    //加密方式
    String algorithmName = AppContext.getProperties(WebConstant.ENCRYPTED_TYPE);

    if (EncryptType.PLAINTEXT.value.equals(algorithmName)) {
      //明文密码，不需要加密
      return plaintext;
    } else if (EncryptType.MD5.value.equals(algorithmName)) {
      // MD5加密
      int hashIterations = Integer.parseInt(AppContext.getProperties(
          WebConstant.ENCRYPTED_NUM));
      try {
        return EncryptUtil.md5(plaintext, salt, hashIterations);
      } catch (UnsupportedEncodingException ex) {
        ex.printStackTrace();
      } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
      }
    } else if (EncryptType.SHA1.value.equals(algorithmName)) {
      // SHA1加密
      int hashIterations = Integer.parseInt(AppContext.getProperties(
          WebConstant.ENCRYPTED_NUM));
      try {
        return EncryptUtil.sha1(plaintext, salt, hashIterations);
      } catch (UnsupportedEncodingException ex) {
        ex.printStackTrace();
      } catch (NoSuchAlgorithmException ex) {
        ex.printStackTrace();
      }
    } else if (EncryptType.BCYRPT.value.equals(algorithmName)) {
      // BCYRPT加密
      return EncryptUtil.bcrypt(plaintext);
    } else {
      return plaintext;
    }

    return plaintext;
  }
}
